﻿using System.Linq;
using Microsoft.SharePoint.Administration;
using Trentacular.SharePoint.Deployment.Model;
using Trentacular.SharePoint.Deployment.Util;

namespace Trentacular.SharePoint.Deployment.Data.Proxy
{
    public class FarmWebApplicationsLazyInitializer : BaseDomainListLazyInitializer<Farm, WebApplication>
    {
        protected override object InitializeTarget()
        {
            var spFarm = SPFarm.Local;
            var service = spFarm.Services.GetValue<SPWebService>("");

            var webApplications = service.WebApplications.Cast<SPWebApplication>()
                .Select(wa => CreateWebApplication(wa))
                .ToVirtualList();

            var caWebApplication = CreateWebApplication(SPAdministrationWebApplication.Local);
            caWebApplication.Name = "Central Administration";
            caWebApplication.DisplayName = caWebApplication.Name;
            webApplications.Add(caWebApplication);

            return webApplications;
        }

        private WebApplication CreateWebApplication(SPWebApplication wa)
        {
            var webApp = wa.CreateDomainObject<WebApplication>();
            webApp.Farm = Owner;
            webApp.Url = GetWebApplicationUrl(wa);
            webApp.Sites = Data.CreateProxiedList<Site>(
                new WebApplicationSitesLazyInitializer { Owner = webApp }
                );

            webApp.Features = Data.CreateProxiedList<WebApplicationFeature>(
                new WebApplicationFeaturesLazyInitializer { Owner = webApp }
                );

            webApp.AvailableFeatureDefinitions = Data.CreateProxiedList<FeatureDefinition>(
                new WebApplicationAvailableFeatureDefinitionsLazyInitializer { Owner = webApp }
                );

            return webApp;
        }

        private string GetWebApplicationUrl(SPWebApplication wa)
        {
            foreach (var alternateUrl in wa.AlternateUrls)
            {
                if (alternateUrl.UrlZone == SPUrlZone.Default)
                    return alternateUrl.IncomingUrl;
            }

            return wa.AlternateUrls[0].IncomingUrl;
        }
    }
}
